from PyQt5.QtWidgets import QOpenGLWidget
from PyQt5.QtGui import QVector3D, QWheelEvent, QMouseEvent
from PyQt5.QtCore import QTimer, Qt
from OpenGL.GL import *
from OpenGL.GLU import *
import math
from collections import deque

class AccelGLWidget(QOpenGLWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.accel = QVector3D(0, 0, 9.8)  # 初始加速度，默认竖直向下
        self.setMinimumSize(300, 300)
        # 定时刷新
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update)
        self.timer.start(30)
        self.str_ = ""

    def set_accel(self, x, y, z):
        self.accel = QVector3D(x, y, z)

    def initializeGL(self):
        glClearColor(0.1, 0.1, 0.1, 1.0)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_COLOR_MATERIAL)

    def resizeGL(self, w, h):
        glViewport(0, 0, w, h)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(45.0, w / h if h != 0 else 1, 1.0, 100.0)
        glMatrixMode(GL_MODELVIEW)

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()

        # 观察点设置
        gluLookAt(0, 0, 10,  # 摄像头位置
                  0, 0, 0,  # 看向原点
                  0, 1, 0)  # 上方向

        # 加速度 -> 倾角
        ax, ay, az = self.accel.x(), self.accel.y(), self.accel.z()
        norm = math.sqrt(ax ** 2 + ay ** 2 + az ** 2)
        if norm == 0:
            norm = 1
        ax, ay, az = ax / norm, ay / norm, az / norm

        # 绕X轴（pitch）和Y轴（roll）旋转
        pitch = math.atan2(ax, math.sqrt(ay ** 2 + az ** 2)) * 180 / math.pi
        roll = math.atan2(ay, az) * 180 / math.pi

        glRotatef(pitch, 1.0, 0.0, 0.0)
        glRotatef(roll, 0.0, 1.0, 0.0)

        # 绘制立方体
        self.draw_cube()

    def draw_cube(self):
        glBegin(GL_QUADS)
        glColor3f(1.0, 0.0, 0.0)  # 红色前面
        glVertex3f(1.0, 1.0, 1.0)
        glVertex3f(-1.0, 1.0, 1.0)
        glVertex3f(-1.0, -1.0, 1.0)
        glVertex3f(1.0, -1.0, 1.0)

        glColor3f(0.0, 1.0, 0.0)  # 绿色后面
        glVertex3f(1.0, 1.0, -1.0)
        glVertex3f(-1.0, 1.0, -1.0)
        glVertex3f(-1.0, -1.0, -1.0)
        glVertex3f(1.0, -1.0, -1.0)

        glColor3f(0.0, 0.0, 1.0)  # 蓝色左侧
        glVertex3f(-1.0, 1.0, 1.0)
        glVertex3f(-1.0, 1.0, -1.0)
        glVertex3f(-1.0, -1.0, -1.0)
        glVertex3f(-1.0, -1.0, 1.0)

        glColor3f(1.0, 1.0, 0.0)  # 黄色右侧
        glVertex3f(1.0, 1.0, 1.0)
        glVertex3f(1.0, 1.0, -1.0)
        glVertex3f(1.0, -1.0, -1.0)
        glVertex3f(1.0, -1.0, 1.0)

        glColor3f(0.0, 1.0, 1.0)  # 青色顶部
        glVertex3f(1.0, 1.0, 1.0)
        glVertex3f(-1.0, 1.0, 1.0)
        glVertex3f(-1.0, 1.0, -1.0)
        glVertex3f(1.0, 1.0, -1.0)

        glColor3f(1.0, 0.0, 1.0)  # 品红底部
        glVertex3f(1.0, -1.0, 1.0)
        glVertex3f(-1.0, -1.0, 1.0)
        glVertex3f(-1.0, -1.0, -1.0)
        glVertex3f(1.0, -1.0, -1.0)
        glEnd()


from collections import deque
from PyQt5.QtWidgets import QOpenGLWidget
from PyQt5.QtCore import QTimer, Qt
from PyQt5.QtGui import QWheelEvent, QPainter, QColor

from OpenGL.GL import *


class AccelPlotGLWidget(QOpenGLWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setMinimumSize(600, 300)
        self.setFocusPolicy(Qt.StrongFocus)  # 确保可以接收到鼠标滚轮事件
        self.data = deque(maxlen=512)
        self.y_min = -4000
        self.y_max = 4000
        self.y_scale = 1.0

        self.str_ = 'y'  # 默认颜色，可通过 setcolor 改变

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update)
        self.timer.start(30)

    def add_point(self, value):
        self.data.append(value)

    def wheelEvent(self, event: QWheelEvent):
        delta = event.angleDelta().y()
        factor = 1
        # 这块逻辑仅供示例，你可以根据需要调整 factor 的变化及范围限制
        if delta < 0:
            self.y_scale = max(0.1, self.y_scale - 0.1)
        else:
            self.y_scale = min(2.0, self.y_scale + 0.1)
        self.update()

    def initializeGL(self):
        glClearColor(0.0, 0.0, 0.0, 1.0)

    def resizeGL(self, w, h):
        glViewport(0, 0, w, h)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        # 保证正交投影区域正确映射数据和y轴范围（乘以缩放因子）
        glOrtho(0, len(self.data) if self.data else 512,
                self.y_min * self.y_scale, self.y_max * self.y_scale,
                -1, 1)
        glMatrixMode(GL_MODELVIEW)

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT)
        glLoadIdentity()

        # ---------------------
        # 绘制网格背景
        # ---------------------
        glColor3f(0.3, 0.3, 0.3)  # 网格颜色：灰色
        glBegin(GL_LINES)
        # 设置横向网格间隔（例如：每 100 个单位，实际间隔随缩放而变化）
        grid_y_interval = 500 * self.y_scale
        # 横向网格：从 y_min 到 y_max
        y = self.y_min * self.y_scale
        while y <= self.y_max * self.y_scale:
            glVertex2f(0, y)
            glVertex2f(len(self.data) if self.data else 512, y)
            y += grid_y_interval

        # 纵向网格：例如每 50 个数据点绘制一条竖直网格线
        grid_x_interval = 50
        x = 0
        xmax = len(self.data) if self.data else 512
        while x <= xmax:
            glVertex2f(x, self.y_min * self.y_scale)
            glVertex2f(x, self.y_max * self.y_scale)
            x += grid_x_interval
        glEnd()

        # ---------------------
        # 绘制坐标轴
        # ---------------------
        glColor3f(1, 1, 1)
        glBegin(GL_LINES)
        # X轴
        glVertex2f(0, 0)
        glVertex2f(xmax, 0)
        # Y轴
        glVertex2f(0, self.y_min * self.y_scale)
        glVertex2f(0, self.y_max * self.y_scale)
        glEnd()

        # ---------------------
        # 绘制加速度曲线
        # ---------------------
        if self.str_ == 'x':
            glColor3f(1, 0, 0)
        elif self.str_ == 'y':
            glColor3f(0, 1, 0)
        elif self.str_ == 'z':
            glColor3f(0, 0, 1)
        else:
            glColor3f(1, 1, 1)

        glBegin(GL_LINE_STRIP)
        for i, val in enumerate(self.data):
            glVertex2f(i, val)
        glEnd()

        # ---------------------
        # 使用 QPainter 绘制 Y 轴数值（文本）
        # ---------------------
        painter = QPainter(self)
        painter.setPen(QColor(255, 255, 255))  # 文本颜色：白色
        font = painter.font()
        font.setPointSize(10)
        painter.setFont(font)

        widget_height = self.height()
        bottom = self.y_min / self.y_scale
        top = self.y_max / self.y_scale

        # 为每条横向网格绘制对应数值标签
        y = bottom
        while y <= top:
            # 这里 label 显示未缩放前的数值
            label_val = y
            # 计算 OpenGL 坐标 y 到窗口像素坐标的转换
            # 由于 glOrtho 中设置的 bottom 为 self.y_min * self.y_scale, top 为 self.y_max * self.y_scale
            # 像素 y 坐标 = (y - bottom) / (top-bottom) * widget_height
            pixel_y = widget_height - ((y - bottom) / (top - bottom) * widget_height)
            # 在窗口左边预留一定空间，绘制文本
            painter.drawText(2, int(pixel_y), f"{label_val:.0f}")
            y += grid_y_interval

        painter.end()

    def setcolor(self, str):
        self.str_ = str

    def mousePressEvent(self, event: QMouseEvent):
        # 右键归位功能：右键点击时恢复 y_scale 为默认值
        if event.button() == Qt.RightButton:
            self.y_scale = 1.0  # 恢复默认缩放
            self.update()